#ifndef VALID_CYCLES_H
#define VALID_CYCLES_H

#ifndef uint
#define uint unsigned int
#endif

#include <vector>

#include "network.h"
#include "list_of_cuts2.h"

using namespace std;

class valid_cycles
{
 public:
  // Constructor
  valid_cycles(network* net, 
	       const double vio = 0.2, 
	       const double e_high = 0.8,
	       const int max_cuts = 1000);
  
  // Funktion to calculate cycles
  list_of_cuts* int_cycles(const vector<double> &y,
			   const bool ECMP);
  list_of_cuts* direct_cycles(const vector<double> &y);

 private:

  // Network
  network* _net;
  int nr_nodes;
  int nr_arcs;
  
  // Parameters for the solution
  double violation_bound;
  double epsilon_high;
  int max_nr_cuts;

  // Variables for calculating the strongly connected parts in grahps
  vector<int> Gabow_sequence;
  vector<int> Gabow_boundary;
 
  // Functions for calculating the strongly connected parts in grahps
  void Gabow_DFS(vector< vector <int> > g, int v, 
		 vector<int> &GabowIndex, int &sequencePtr, 
		 int &boundaryPtr, int &cnt);
  void getStrongComponents( vector< vector <int> > g, 
			    vector<int> &GabowIndex, 
			    int &nComponents);

  // Help functions
  void create_d(vector<vector <int> > &from, 
		vector<vector<int> > &to,
		const int dest);
  vector<vector <int> > create_G_bar(const vector< vector<int> > &AF,
				     const vector< vector<int> > &DF,
				     const vector< vector<int> > &AB,
				     const vector< vector<int> > &DB);
  vector<int> find_cycle(const vector< vector<int> > &G_bar, 
			 const vector<int> &C,
			 const int start_e);

  // Functions to calculate the constrains
  void create_constrain(list_of_cuts* cuts,
			const vector<int> &path, 
			const vector<vector<int> > &G_bar,
			const vector<double> &y_val, 
			const vector<int> &C,
			const int dest_f, const int dest_b);
  void create_constrain_ECMP(list_of_cuts* cuts,
			     const vector<int> &path, 
			     const vector<vector<int> > &G_bar,
			     const vector<double> &y_val, 
			     const vector<int> &C,
			     const int dest_f, const int dest_b);

  // Help functions to calculate the constrains
  void clique_dest(vector<int> &y_var);
  double check_violation(const vector<double> &y_val,
			 const vector<int> &var,
			 const vector<double> &coef,
			 const double rhs);
  int change_dest(int val, const int dest_1, const int dest_2);
};
#endif
